/*****************************
 *  -----------------------  *
 * DRobot (Take the Control) *
 *  -----------------------  *
 *****************************/
package com.drobot.window;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.RECT;
import com.sun.jna.win32.StdCallLibrary;

public class Window {

	public interface User32 extends StdCallLibrary {
		User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);

		interface WNDENUMPROC extends StdCallCallback {
            boolean callback(HWND hWnd, Pointer arg);
        }

        boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg);
		
		int GetWindowTextA(HWND hWnd, byte[] lpString, int nMaxCount);

		boolean GetWindowRect(HWND hWnd, RECT rect);
		
		boolean MoveWindow(HWND hWnd, int x, int y, int nWidth, int nHeight, boolean bRepaint);

		HWND FindWindowA(String windowClass,String windowName);
		
		boolean ShowWindow(HWND hWnd, int nCmdShow);
		
		boolean CloseWindow(HWND hWnd);
	}

	private HWND findWindowByName(String windowName){
		HWND hWnd = User32.INSTANCE.FindWindowA(null, windowName);
		return hWnd;
	}
	
	private RECT getWindowRect(String windowName){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return null;
		RECT rect = new RECT();
		User32.INSTANCE.GetWindowRect(hWnd, rect);
		return rect;
	}
	
	
	public boolean moveWindow(String windowName, int x, int y){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		RECT rect = getWindowRect(windowName);
		int width = rect.right -rect.left;
		int height = rect.bottom -rect.top;
		User32.INSTANCE.MoveWindow(hWnd, x, y, width, height, false);
		return true;
	}
	
	public boolean resizeWindow(String windowName, int width, int height){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		RECT rect = getWindowRect(windowName);
		int x = rect.left;
		int y = rect.top;
		User32.INSTANCE.MoveWindow(hWnd, x, y, width, height, false);
		return true;
	}
	
	public boolean existWindow (String windowName){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		return true;
	}
	
	static String windowName;
	
	public String findWindowBySize(final int width, final int height){
		User32.INSTANCE.EnumWindows(new User32.WNDENUMPROC() {
            public boolean callback(HWND hWnd, Pointer userData) {
                byte[] windowText = new byte[512];
                User32.INSTANCE.GetWindowTextA(hWnd, windowText, 512);
                String wText = Native.toString(windowText);
                RECT rect = getWindowRect(wText);
                if ((rect.right - rect.left) == width && (rect.bottom - rect.top) == height) {
                	windowName = wText;
                }
                return true;
            }
        }, null);
		return windowName;
	}
	
	public boolean minimize(String windowName){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		User32.INSTANCE.ShowWindow(hWnd, 6);
		return true;
	}
	
	public boolean maximize(String windowName){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		User32.INSTANCE.ShowWindow(hWnd, 3);
		return true;
	}
	
	public boolean restore(String windowName){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		User32.INSTANCE.ShowWindow(hWnd, 9);
		return true;
	}
	
	public boolean close(String windowName){
		HWND hWnd = findWindowByName(windowName);
		if (hWnd == null)
			return false;
		User32.INSTANCE.CloseWindow(hWnd);
		return true;
	}

}
